﻿using System;
using System.ComponentModel;
using System.Web.UI;
using System.Xml.Linq;

namespace SPAdaptiveMenu.Controls
{
    /// <summary>
    /// Menu item base class
    /// </summary>
    [TypeConverter(typeof(ExpandableObjectConverter))]
    public class MenuItem : Control, IHierarchyData
    {
        /// <summary>
        /// Menu text
        /// </summary>
        public string Title { get; set; }
        /// <summary>
        /// Menu description. Used only in large mode
        /// </summary>
        public string Description { get; set; }
        /// <summary>
        /// URL of menu icon
        /// </summary>
        public string IconSrc { get; set; }
        /// <summary>
        /// Tooltip of menu icon
        /// </summary>
        public string IconToolTip { get; set; }
        /// <summary>
        /// Type of menu
        /// </summary>
        public virtual MenuItemType ItemType { get; set; }
        /// <summary>
        /// Hidden flag
        /// </summary>
        public bool Hidden { get; set; }
        /// <summary>
        /// Disabled flag
        /// </summary>
        public bool Disabled { get; set; }

        protected MenuItem()
        {
            Title = string.Empty;
            Description = string.Empty;
            IconSrc = string.Empty;
            IconToolTip = string.Empty;
            Disabled = false;
        }

        protected override void Render(HtmlTextWriter writer)
        {
            writer.Write(string.Empty);
        }

        public IHierarchicalEnumerable GetChildren()
        {
            if (this is MenuNested)
            {
                return ((MenuNested)this).ItemCollection;
            }
            return null;
        }

        public IHierarchyData GetParent()
        {
            return Parent as MenuItem;
        }

        public bool HasChildren
        {
            get { return (this is MenuNested) && ((MenuNested)this).ItemCollection.Count > 0; }
        }

        public string Path
        {
            get { return (GetParent() == null ? string.Empty : GetParent().Path) + ID; }//TODO
        }

        public object Item
        {
            get { return this; }
        }

        public string Type
        {
            get { return GetType().Name; }
        }

        protected internal virtual XElement Serialized
        {
            get
            {
                return new XElement("MenuItem",
                    new XAttribute("Title", Title ?? string.Empty),
                    new XAttribute("Description", Description ?? string.Empty),
                    new XAttribute("IconSrc", IconSrc ?? string.Empty),
                    new XAttribute("IconToolTip", IconToolTip ?? string.Empty),
                    new XAttribute("Disabled", Disabled),
                    new XAttribute("Hidden", Hidden));
            }
        }

        protected internal virtual XElement HTML
        {
            get
            {
                XNamespace ie = "ie";
                var element = new XElement(ie+"menuitem",
                    new XAttribute("id", ClientID ?? string.Empty),
                    new XAttribute("text", Title ?? string.Empty),
                    new XAttribute("title", Title ?? string.Empty),
                    new XAttribute("description", Description ?? string.Empty),
                    new XAttribute("iconSrc", IconSrc ?? string.Empty),
                    new XAttribute("iconAltText", IconToolTip ?? string.Empty),
                    new XAttribute("enabled", !Disabled),
                    new XAttribute("hidden", Hidden));
                return element;
            }
        }

        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            Page.RegisterRequiresControlState(this);
        }

        protected override object SaveControlState()
        {
            base.SaveControlState();
            var obj = base.SaveControlState();
            return obj != null
                ? (object)new Pair(obj, Serialized.ToString())
                : Serialized.ToString();
        }

        protected override void LoadControlState(object state)
        {
            if (state == null) return;
            var p = state as Pair;
            if (p != null)
            {
                base.LoadControlState(p.First);
                InitProperties(XElement.Parse((string)p.Second));
            }
            else
            {
                if (state is string)
                    InitProperties(XElement.Parse((string)state));
                else
                    base.LoadControlState(state);
            }
        }

        protected internal virtual void InitProperties(XElement element)
        {
            if (element == null) return;
            Title = element.Attribute("Title").Value;
            Description = element.Attribute("Description").Value;
            IconSrc = element.Attribute("IconSrc").Value;
            IconToolTip = element.Attribute("IconToolTip").Value;
            Disabled = element.Attribute("Disabled").Value.Equals("TRUE", StringComparison.InvariantCultureIgnoreCase);
            Hidden = element.Attribute("Hidden").Value.Equals("TRUE", StringComparison.InvariantCultureIgnoreCase);
        }

    }
}
